/**
 * @class UI-面板-新手引导面板
 * @author DuskyHuang 圣子
 * @description 首次登陆弹出、可以在设置栏主动调出。
 * 
 * 引导步骤说明:
 * position of screenshot:
 * step1: 100, 70       shot1:  右下_扩展 ↑↑ flash ↓
 * step2: 100, 0        shot2:  左_侧栏，右_标尺 ↑
 * step3:-200, 80       shot3:  右下_扩展 ↓ 右下，左下 ↑
 * step4: -50, 0        shot4:  左_侧栏 ↓ 右侧_按钮，右侧_按钮 ↑
 * step5: -50, -150     shot5:  右侧_按钮，右侧_按钮 ↓ 上_菜单 ↑
 * step6:  80, -150     shot6:  x
 * step7:-100, -150     shot7:  x
 * step8:-220, -25      shot8:  上_状态、下_底左、下_底右 ↑
 * step9:-100, -100     shot9:  上_状态、下_底左、下_底右 ↓
 * step10:  0, 0        shot10:  opa=0
 * step-over:a=255      shot-over:
 * step:20frame
 * step-continue:5frame
*/

import { _decorator, Node, Animation, UIOpacity, EventTouch, Label, sys, Sprite } from 'cc';
import { UI } from "notifications";
import { core, Mediator } from 'cfw';
import { Res } from 'const';
import { ui, user } from 'proxies';
import { changeFrame } from 'helpers';
const { ccclass, property } = _decorator;

@ccclass('cocosmos.guide-panel')
export class GuidePanel extends Mediator {

    @property(Node) public steps: Node = null;
    @property(Node) public screenshot: Node = null;
    @property(Node) public overTip: Node = null;
    @property(Node) public mask: Node = null;
    @property(Node) public btnNext: Node = null;
    @property(Node) public btnSkip: Node = null;
    @property(Node) public langChoose: Node = null;
    @property(Node) public skipDialog: Node = null;
    @property(Node) public title: Node = null;
    @property(Label) public labelStep: Label = null;
    @property([Sprite]) public langSprites: Sprite[] = [];

    protected onLoad(): void {
        this._ss_anim = this.screenshot.getComponent(Animation);
        this._ss_anim.on(FINISHED, this.onStepStart, this);
    }

    protected start(): void {
        this._adapt();
    }

    protected onEnable(): void {
        this._toggleSkip(false)._toggleNext(false);
        this.langChoose.active = this.steps.active = this.overTip.active = false;
        this.steps.children.forEach(child => child.active = child === this.title);
        this.labelStep.string = '_';
        this.screenshot.getComponentsInChildren(UIOpacity).forEach(opa => opa.opacity = 0);
        if (!user.guided) {
            this._darkenMask = false;
            this.langChoose.active = true;
            this.langChoose.getComponent(Animation).play();
        } else {
            this._startSteps();
        }
    }
    
    protected chooseLang(evt: EventTouch, lang: language): void {
        this.notify(UI.LANGUAGE, lang);
        this.langChoose.active = false;
        this._startSteps();
    }
    
    private _startSteps(): void {
        this.changeSpriteLang();
        this.steps.active = this.screenshot.active = true;
        this._darkenMask = true;
        this._idx = 0;
        this._playNextStep();
    }

    protected clickNext(): void {
        if (this._idx >= TOTAL_STEPS) {
            this._playOverTip();
        } else this._playNextStep();
    }

    protected clickSkip(): void {
        this.skipDialog.active = true;
        this.skipDialog.getComponent(Animation).play();
    }

    protected clickConfirm(): void {
        this.skipDialog.active = false;
        this._playOverTip();
    }

    protected clickCancel(): void {
        this.skipDialog.active = false;
    }

    protected changeSpriteLang(): void {
        const { language } = ui, POPS = Res.Sheets.UI_POPS, en = language === 'en';
        this.langSprites.forEach(spt => changeFrame(spt, POPS, 'en', en));
    }

    private _playOverTip(): void {
        user.updateGuided();
        this.steps.active = false;
        this.overTip.active = true;
        this._toggleNext(false)._toggleSkip(false);
        this.getComponent(Animation).play('over-tip');
    }

    protected onOverTipCompete(): void {
        core.audio.bgmVolume = 0.5;
        this.notify(UI.Panels.CLOSE, Res.Prefabs.GUIDE_PANEL);
    }

    private _playNextStep(): void {
        // step1: hide last and show this
        this._toggleStep(false);
        this._idx++;
        this._toggleNext(false);
        this.labelStep.string = `（${this._idx}/${TOTAL_STEPS}）`;
        // step2: play animations
        const shot_name = 'shot-' + this._idx;
        const shot = this._ss_anim.clips.find(clip => clip.name === shot_name);
        if (shot) this._ss_anim.play(shot_name);
        else this.onStepStart();
    }

    protected onStepStart(): void {
        this._toggleStep(true);
        const opa = this._step.getComponent(UIOpacity);
        opa.opacity = 0;
        this.scheduleOnce(() => opa.opacity = 255);
        const anim = this._step.getComponent(Animation);
        anim.once(FINISHED, this.onStepOver, this);
        anim.play();
    }

    protected onStepOver(): void {
        if (this._idx === 1) this._toggleSkip(true);
        this._toggleNext(true);
    }

    private set _darkenMask(arg: boolean) {
        this.mask.getComponent(UIOpacity).opacity = arg ? 232 : 0;
    }

    private _toggleNext(show: boolean): this {
        this.btnNext.active = show;
        return this;
    }

    private _adapt(): void {
        const step10 = this.steps.getChildByName("step-10");
        const key = sys.isMobile ? 'mb' : 'pc';
        step10.children.forEach(child => {
            const pad = child.getChildByName('pad');
            if (pad) pad.active = child.name.includes(key);
        });
    }

    private _toggleSkip(show: boolean): this { this.btnSkip.active = show; return this; }
    private _toggleStep(show: boolean): this { const step = this._step; if (step) step.active = show; return this; }
    private get _step(): Node { return this.steps.getChildByName('step-' + this._idx); }
    private _idx: num.int = -1;
    private _ss_anim: Animation = null;
}

const { FINISHED } = Animation.EventType;
const TOTAL_STEPS = 10;